package com.ikingtech.platform.service.system.division.service;

import com.ikingtech.framework.sdk.component.api.CompDivisionApi;
import com.ikingtech.framework.sdk.component.model.DivisionElement;
import com.ikingtech.framework.sdk.division.model.DivisionDTO;
import com.ikingtech.framework.sdk.enums.system.division.DivisionLevelEnum;
import com.ikingtech.framework.sdk.utils.Tools;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
public abstract class AbstractCompDivisionService implements CompDivisionApi {

    private final StringRedisTemplate redisTemplate;

    @Override
    public List<DivisionElement> load(DivisionLevelEnum level, Long parentCode) {
        List<String> cachedDivisionInfos;
        if (null == parentCode) {
            if (level.equals(DivisionLevelEnum.PROVINCE)) {
                cachedDivisionInfos = this.redisTemplate.opsForList().range(DivisionLevelEnum.PROVINCE.cacheKey(), 0, -1);
            } else {
                cachedDivisionInfos = new ArrayList<>();
                Set<String> currentLevelDivisionCacheKeys = this.redisTemplate.keys(level.cacheKey() + ":*");
                if (currentLevelDivisionCacheKeys != null) {
                    currentLevelDivisionCacheKeys.forEach(key -> {
                        List<String> currentLevelDivisionInfos = this.redisTemplate.opsForList().range(key, 0, -1);
                        if (currentLevelDivisionInfos != null) {
                            cachedDivisionInfos.addAll(currentLevelDivisionInfos);
                        }
                    });
                }
            }
        } else {
            cachedDivisionInfos = this.redisTemplate.opsForList().range(level.cacheKey(parentCode), 0, -1);
        }
        return Tools.Coll.convertListWithSort(cachedDivisionInfos, cachedDivisionInfo -> {
            DivisionDTO division = Tools.Json.toBean(cachedDivisionInfo, DivisionDTO.class);
            DivisionElement divisionElement = new DivisionElement();
            if (null != division) {
                divisionElement.setCode(division.getCode());
                divisionElement.setName(division.getName());
                divisionElement.setParentCode(division.getParentCode());
                divisionElement.setLevel(division.getDivisionLevel());
                if (null != divisionElement.getLevel()) {
                    divisionElement.setLevelName(divisionElement.getLevel().description);
                }
                divisionElement.setCategory(division.getDivisionCategory());
                if (null != divisionElement.getCategory()) {
                    divisionElement.setCategoryName(divisionElement.getCategory().description);
                }
            }
            return divisionElement;
        }, DivisionElement::getCode);
    }
}
